﻿using System;
using System.Collections.Generic;
using System.Text;
using BCS.Common;
using BCS.Model;
using BCS.NativeBusiness;

namespace BCS.Business
{
        /// <summary>
        /// 表示摄像机
        /// </summary>
        public class Camera : NativeCamera
        {
                #region 构造函数

                /// <summary>
                /// 初始化摄像机
                /// </summary>
                /// <param name="model">摄像机数据模型</param>
                public Camera(CameraModel model)
                {
                        Model = model;
                        TransportState = TransportState.无坯;
                        TransportStateHisory = new List<TransportState>(7);
                }

                #endregion 构造函数

                #region 属性

                public Byte Brightness
                {
                        get
                        {
                                return (byte)Model.Brightness;
                        }
                        set
                        {
                                Model.Brightness = value;
                                GraphicsCard.SetBrightness(value);
                        }
                }

                public byte Contrast
                {
                        get
                        {
                                return (byte)Model.Contrast;
                        }
                        set
                        {
                                Model.Contrast = value;
                                GraphicsCard.SetContrast(value);
                        }
                }

                public int Count
                {
                        get
                        {
                                return Model.Count;
                        }
                        set
                        {
                                if (Model.Count != value)
                                {
                                        Model.Count = value;
                                }
                        }
                }

                public int ForeX
                {
                        get
                        {
                                return Model.ForeX;
                        }
                        set
                        {
                                if (Model.ForeX != value)
                                {
                                        Model.ForeX = value;
                                }
                        }
                }

                public int ForeY
                {
                        get
                        {
                                return Model.ForeY;
                        }
                        set
                        {
                                if (Model.ForeY != value)
                                {
                                        Model.ForeY = value;
                                }
                        }
                }

                public int BackX
                {
                        get
                        {
                                return Model.BackX;
                        }
                        set
                        {
                                if (Model.BackX != value)
                                {
                                        Model.BackX = value;
                                }
                        }
                }

                public int BackY
                {
                        get
                        {
                                return Model.BackY;
                        }
                        set
                        {
                                if (Model.BackY != value)
                                {
                                        Model.BackY = value;
                                }
                        }
                }

                public int ForeAeraLeft
                {
                        get
                        {
                                return ForeX;
                        }
                }

                public int ForeAeraTop
                {
                        get
                        {
                                return ForeY;
                        }
                }

                public int ForeAeraRight
                {
                        get
                        {
                                return ForeX + Global.AeraWidth;
                        }
                }

                public int ForeAeraBottom
                {
                        get
                        {
                                return ForeY + Global.AeraHeight;
                        }
                }

                public int BackAeraLeft
                {
                        get
                        {
                                return BackX;
                        }
                }

                public int BackAeraTop
                {
                        get
                        {
                                return BackY;
                        }
                }

                public int BackAeraRight
                {
                        get
                        {
                                return BackX + Global.AeraWidth;
                        }
                }

                public int BackAeraBottom
                {
                        get
                        {
                                return BackY + Global.AeraHeight;
                        }
                }

                /// <summary>
                /// 获取或属性摄像机数据模型
                /// </summary>
                public CameraModel Model { get; protected set; }

                /// <summary>
                /// 获取或设置摄像机所属采集卡
                /// </summary>
                public GraphicsCard GraphicsCard
                {
                        get
                        {
                                return BusinessCache.Instance.GraphicsCard;
                        }
                }

                public byte[,] RawBuffer = new byte[Global.AeraHeight + 4, Global.AeraWidth + 4];

                //public Byte[] HAverage = new Byte[Global.AeraHeight];
                public Byte[] VAverage = new Byte[Global.AeraWidth];

                public int LeftLight = -1;
                public int RightLight = -1;
                public int HMiddle = Global.AeraWidth / 2;
                public int LeftPosition = 7;
                public int RightPosition = Global.AeraWidth - 8;

                //public int TopLight = -1;
                //public int BottomLight = -1;
                //public int VMiddle = Global.AeraHeight / 2;

                public int PixelsTotal = Global.AeraWidth * Global.AeraHeight;
                public int LightPixelsCount = 0;
                public byte BackPixel = 0;

                public TransportState TransportState { get; set; }

                public List<TransportState> TransportStateHisory { get; private set; }

                private StringBuilder sb = new StringBuilder();

                #endregion 属性

                #region 方法

                public unsafe void UpdateForeBuffer()
                {
                        for (int y = 0; y < Global.AeraHeight; y++)
                        {
                                for (int x = 0; x < Global.AeraWidth; x++)
                                {
                                        SourceBuffer[y * Global.AeraWidth + x] = GetPixel(x + ForeX, y + ForeY);
                                }
                        }
                }

                public unsafe void UpdateBackBuffer()
                {
                        int total = 0;
                        for (int y = 0; y < Global.AeraHeight; y++)
                        {
                                for (int x = 0; x < Global.AeraWidth; x++)
                                {
                                        BackBuffer[y * Global.AeraWidth + x] = GetPixel(x + BackX, y + BackY);
                                        total += BackBuffer[y * Global.AeraWidth + x];
                                }
                        }

                        BackPixel = (byte)(total / PixelsTotal);
                }

                public unsafe void UpdateSubBuffer()
                {
                        int total = PixelsTotal;

                        for (int x = 0; x < total; x++)
                        {
                                SubBuffer[x] = SourceBuffer[x] - BackPixel > 25 ? (Byte)255 : (Byte)0;
                        }
                }

                //public unsafe void UpdateHAverage()
                //{
                //        int total = 0;
                //        int start = 0;
                //        for (int y = 0; y != Global.AeraHeight; y++)
                //        {
                //                start = y * Global.AeraWidth;
                //                total = 0;
                //                for (int x = 0; x != Global.AeraWidth; x++)
                //                {
                //                        total += SubBuffer[start + x];
                //                }

                //                HAverage[y] = Filter(total / Global.AeraWidth);
                //        }
                //}

                public unsafe void UpdateVAverage()
                {
                        int total = 0;
                        for (int x = 0; x != Global.AeraWidth; x++)
                        {
                                total = 0;
                                for (int y = 0; y != Global.AeraHeight; y++)
                                {
                                        total += SubBuffer[y * Global.AeraWidth + x];
                                }

                                VAverage[x] = Filter(total / Global.AeraHeight);
                        }
                }

                public unsafe void Analyse()
                {
                        StringBuilder sb = null;
                        if (BusinessCache.Instance.DebugWriter != null)
                        {
                                sb = new StringBuilder();
                        }

                        //填充分析区域
                        UpdateForeBuffer();
                        UpdateBackBuffer();
                        UpdateSubBuffer();

                        if (!BusinessCache.Instance.IsAutoCount)
                        {
                                return;
                        }

                        //UpdateHAverage();
                        UpdateVAverage();

                        LeftLight = -1;
                        for (int i = Global.AeraWidth - 3; i != 1; i--)
                        {
                                if (VAverage[i - 2] > 128
                                        && VAverage[i - 1] > 128
                                        && VAverage[i] > 128
                                        && VAverage[i + 1] > 128
                                        && VAverage[i + 2] > 128)
                                {
                                        LeftLight = i;
                                }
                        }

                        if (sb != null)
                        {
                        }

                        RightLight = -1;
                        for (int i = 2; i != Global.AeraWidth - 2; i++)
                        {
                                if (VAverage[i - 2] > 128
                                        && VAverage[i - 1] > 128
                                        && VAverage[i] > 128
                                        && VAverage[i + 1] > 128
                                        && VAverage[i + 2] > 128)
                                {
                                        RightLight = i;
                                }
                        }

                        if (sb != null)
                        {
                                sb.AppendLine("VAverage:");
                                foreach (var item in VAverage)
                                {
                                        sb.Append(item);
                                        sb.Append(" ");
                                }
                                sb.AppendLine();

                                sb.AppendLine("LeftLight: " + LeftLight);
                                sb.AppendLine("RightLight: " + RightLight);
                                sb.AppendLine("TransportState: " + TransportState);
                                sb.AppendLine("CountTicks: " + BusinessCache.Instance.CountTicks);

                                sb.Append("History :");
                                foreach (var item in TransportStateHisory)
                                {
                                        sb.Append(item);
                                        sb.Append(" ");
                                }
                                sb.AppendLine();

                                sb.AppendLine("处理：");
                        }

                        switch (TransportState)
                        {
                                case TransportState.无坯:
                                        //if (TransportStateHisory.Count == 3)
                                        //{
                                        //        if (BusinessCache.Instance.CountTicks > 10)
                                        //        {
                                        //                //right to left,increase
                                        //                if (TransportStateHisory[0] == TransportState.坯头
                                        //                && TransportStateHisory[1] == TransportState.满坯
                                        //                        && TransportStateHisory[2] == TransportState.坯尾)
                                        //                {
                                        //                        BusinessCache.Instance.InsertRecord(1);
                                        //                        BusinessCache.Instance.CurrentTeamCount += Count;
                                        //                        BusinessCache.Instance.TotalCount += Count;

                                        //                        BusinessCache.Instance.CountTicks = 0;
                                        //                }

                                        //                //left to right,decrease
                                        //                if (TransportStateHisory[0] == TransportState.坯尾
                                        //                && TransportStateHisory[1] == TransportState.满坯
                                        //                        && TransportStateHisory[2] == TransportState.坯头)
                                        //                {
                                        //                        BusinessCache.Instance.InsertRecord(-1);
                                        //                        BusinessCache.Instance.CurrentTeamCount -= Count;
                                        //                        BusinessCache.Instance.TotalCount -= Count;

                                        //                        BusinessCache.Instance.CountTicks = 0;
                                        //                }
                                        //        }
                                        //}

                                        if (TransportStateHisory.Count > 2 && BusinessCache.Instance.CountTicks > 10)
                                        {
                                                //right to left,increase
                                                for (int i = 0; i < TransportStateHisory.Count - 2; i++)
                                                {
                                                        if (TransportStateHisory[i] == TransportState.坯头
                                                        && TransportStateHisory[i + 1] == TransportState.满坯
                                                                && TransportStateHisory[i + 2] == TransportState.坯尾)
                                                        {
                                                                BusinessCache.Instance.InsertRecord(1);
                                                                BusinessCache.Instance.CurrentTeamCount += Count;
                                                                BusinessCache.Instance.TotalCount += Count;

                                                                BusinessCache.Instance.CountTicks = 0;
                                                        }

                                                        //left to right,decrease
                                                        if (TransportStateHisory[i] == TransportState.坯尾
                                                        && TransportStateHisory[i + 1] == TransportState.满坯
                                                                && TransportStateHisory[i + 2] == TransportState.坯头)
                                                        {
                                                                BusinessCache.Instance.InsertRecord(-1);
                                                                BusinessCache.Instance.CurrentTeamCount -= Count;
                                                                BusinessCache.Instance.TotalCount -= Count;

                                                                BusinessCache.Instance.CountTicks = 0;
                                                        }
                                                }
                                        }

                                        TransportStateHisory.Clear();

                                        if (LeftLight < RightPosition
                                                && LeftLight > -1
                                                && RightLight > RightPosition)
                                        {
                                                TransportState = TransportState.坯头;
                                                TransportStateHisory.Add(TransportState);

                                                BusinessCache.Instance.CountTicks = 1;

                                                break;
                                        }

                                        if (LeftLight < LeftPosition
                                                && LeftLight > -1
                                                && RightLight > LeftPosition)
                                        {
                                                TransportState = TransportState.坯尾;
                                                TransportStateHisory.Add(TransportState);

                                                BusinessCache.Instance.CountTicks = 1;

                                                break;
                                        }

                                        break;

                                case TransportState.坯头:

                                        if (LeftLight < LeftPosition
                                                && LeftLight > -1
                                                && RightLight > RightPosition)
                                        {
                                                TransportState = TransportState.满坯;
                                                TransportStateHisory.Add(TransportState);
                                                break;
                                        }

                                        if (LeftLight == -1
                                                && RightLight == -1)
                                        {
                                                TransportState = TransportState.无坯;
                                        }

                                        break;
                                case TransportState.满坯:

                                        if (LeftLight < LeftPosition
                                                && LeftLight > -1
                                                && RightLight > LeftPosition
                                                && RightLight < RightPosition)
                                        {
                                                TransportState = TransportState.坯尾;
                                                TransportStateHisory.Add(TransportState);
                                                break;
                                        }

                                        if (LeftLight < RightPosition
                                                && LeftLight > -1
                                                && RightLight > RightPosition)
                                        {
                                                TransportState = TransportState.坯头;
                                                TransportStateHisory.Add(TransportState);

                                                break;
                                        }

                                        break;

                                case Business.TransportState.坯尾:

                                        if (LeftLight == -1
                                                && RightLight == -1)
                                        {
                                                TransportState = TransportState.无坯;
                                                break;
                                        }

                                        if (LeftLight < LeftPosition
                                                && LeftLight > -1
                                                && RightLight > RightPosition)
                                        {
                                                TransportState = TransportState.满坯;
                                                TransportStateHisory.Add(TransportState);
                                                break;
                                        }
                                        break;

                                default: break;
                        }

                        if (sb != null)
                        {
                                BusinessCache.Instance.DebugWriter.Write(sb.ToString());
                        }
                }

                public byte Filter(int data)
                {
                        if (data > 255)
                        {
                                return (Byte)255;
                        }

                        if (data < 0)
                        {
                                return 0;
                        }

                        return (byte)data;
                }

                #endregion 方法
        }
}